7.8

#include <stdio.h>
#include <curses.h>
#include <time.h>
#include <string.h>

#define DFL_STRING "Hello, world"
#define DFL_BLANK  "            "


void fill_blk(char [], int);

int main(int argc, char **argv)
{
    char *str;
    char blk[BUFSIZ];
    if (argc == 2){
        str = argv[1];
        fill_blk(blk, strlen(str));
    }else{
        str = DFL_STRING;
        strcpy(blk, DFL_BLANK);
    }
    initscr();
    clear();
    while (1){
        move(10, 20);
        standout();
        addstr(str);
        standend();
        move(LINES - 1, 0);
        refresh();
        sleep(1);
        move(10, 20);
        addstr((char *)blk);
        move(LINES - 1, 0);
        refresh();
        sleep(1);  /* DO NOT forget sleep at here */
    }
    endwin();
    return 0;
}

void fill_blk(char blank[], int n)
{
    int i;
    for (i = 0; i < n; i++)
        blank[i] = ' ';
    blank[n] = '\0';
}

7.9

/* icat.c
 * purpose      To show a file's content with theater marquee or Ticker Tape
 * compile      cc icat.c -lcurses -o icat
 */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <curses.h>
#include <stdlib.h>
#include <fcntl.h>

#define DEBUG

int strisdigit(const char *);
const char *checknumarg(const char *, const char *);
int parsearg(int, char **, char **, int *, int *, int *);


int main(int argc, char **argv)
{
    char *path;
    char buf[BUFSIZ];
    char blk[BUFSIZ];
    int length = 100, speed = 1, pos = 10, fd, size, line = 3;
    int i;
    if(parsearg(argc, argv, &path, &length, &speed, &pos))
        return 1;
    for (i = 0; i < length; i++){
        blk[i] = ' ';
    }
    blk[length] = '\0';
    if ((fd = open(path, O_RDONLY)) == -1){
        perror(path);
        return 1;
    }
#ifdef DEBUG
    printf("Path: %s, Length: %d, Speed: %d, Position: %d\n", path, length, speed, pos);
#endif
    initscr();
    clear();
    int j = 0;
    while(1){
        if ((size = read(fd, buf, length)) >= 0){
            for (i = 0; i < size; i ++){
                if (buf[i] == '\n'){
                    line ++;
                    j = 0;
                    continue;
                }
                if (line > LINES - 3){
                    clear();
                    line = 3;
                }
                mvaddch(line, pos+j, buf[i]);
                refresh();
                usleep(100000 - (speed * 1000));
                j++;
            }
        }else{
            perror(path);
            return 1;
        }
        /* move(pos, pos); */
        /* addstr(blk); */
        /* refresh(); */
    }
    endwin();
    return 0;
}

int strisdigit(const char *s)
{
    int n = strlen(s), i;
    char t;
    for (i = 0; i < n; i++){
        t = s[i];
        if (!(t >= '0' && t <= '9'))
            return 0;
    }
    return 1;
}

const char *checknumarg(const char *arg, const char *argv)
{
    if (!strisdigit(argv)){
        fprintf(stderr, "Ivalid value '%s' for argument '%s', need a number\n", argv, arg);
        exit(1);
    }
    return argv;
}

int parsearg(int argc, char **argv, char **path, int *length, int *speed, int *pos)
{
    int i;
    char *tmp;
    if (argc == 1){
        fprintf(stderr, "Usage: %s FILEPATH -l [LENGTH] -s [SPEED] -p [POSITION]\n", *argv);
        return 1;
    }else{
        for (i = 1; i < argc; i++){
            if (strcmp(argv[i], "-l") == 0){
                if (argc < (i + 2)){
                    fprintf(stderr, "No value for argument: %s\n", argv[i]);
                    return 1;
                }
                tmp = (char *)checknumarg(argv[i], argv[i+1]);
                *length = atoi(tmp);
                i++;
            }else if (strcmp(argv[i], "-s") == 0){
                if (argc < (i + 2)){
                    fprintf(stderr, "No value for argument: %s\n", argv[i]);
                    return 1;
                }
                tmp = (char *)checknumarg(argv[i], argv[i+1]);
                *speed = atoi(tmp);
                i++;
            }else if (strcmp(argv[i], "-p") == 0){
                if (argc < (i + 2)){
                    fprintf(stderr, "No value for argument: %s\n", argv[i]);
                    return 1;
                }
                tmp = (char *)checknumarg(argv[i], argv[i+1]);
                *pos = atoi(tmp);
                i++;
            }else{
                *path = argv[i];
            }
        }
        if (!*path){
            fprintf(stderr, "Usage: %s FILEPATH -l [LENGTH] -s [SPEED] -p [POSITION]\n", *argv);
            return 1;
        }
    }
    return 0;
}